<?php

/**
 * IP及CURL辅助组件
 * 
 * @author Lonxon
 * @version 1.5 Core
 */
class Core_Plugin_Tool {

    /**
     * 验证手机号
     * 
     * @param string $mobile 手机号
     * @return boolean
     */
    static public function isMobile($mobile) {
        if ($mobile && is_string($mobile)) {
            return preg_match("/^1[34578][0-9]{9}$/", $mobile) ? true : false;
        }
        return false;
    }

    /**
     * 验证经纬度
     * 
     * @param string $lat 纬度
     * @param string $lng 经度
     * @return boolean
     */
    static public function isLatLng($lat, $lng) {
        if ($lat && $lng && is_string($lat) && is_string($lng)) {
            return preg_match('/^(\d+)\.(\d+)$/', $lat) && preg_match('/^(\d+)\.(\d+)$/', $lng) ? true : false;
        }
        return false;
    }

    /**
     * 验证流水号
     * 
     * @param string $tno 流水号
     * @return boolean
     */
    static public function isTradeNo($tno) {
        if ($tno && is_string($tno)) {
            return preg_match('/^\d{25,32}$/', $tno) ? true : false;
        }
        return false;
    }

    /**
     * 字符编码转换
     * 
     * @param string $data 字符串
     * @return string
     */
    static public function convertChar($data) {
        if (! empty($data)) {
            $fileType = mb_detect_encoding($data, array(
                'ASCII',
                'UTF-8',
                'GB2312',
                'GBK',
                'BIG5'
            ));
            if ($fileType != 'UTF-8') {
                $data = mb_convert_encoding($data, 'utf-8', $fileType);
            }
        }
        return $data;
    }

    /**
     * 字符串正则判断
     * 
     * @param string $str 字符串
     * @param string $type <pre>类型
     *        op => OPENID
     *        wx => TOKEN/JSSIGN
     * @return boolean/string
     */
    static public function checkStr($str, $type) {
        $type = $type && is_string($type) && in_array($type, array(
            'op',
            'wx'
        )) ? $type : false;
        $str = $str && is_string($str) ? trim($str) : false;
        if ($type && $str) {
            switch ($type) {
                case 'op':
                    return preg_match('/^[a-zA-Z0-9-_]{28}$/', $str) ? $str : false;
                    break;
                case 'wx':
                    return preg_match('/^[0-9]{10}:.+$/', $str) ? true : false;
                    break;
                default:
                    $chars = array();
                    $str = str_ireplace("'", '\\\'', $str);
                    $str = strip_tags($str);
                    $str = preg_replace('/\n/is', '', $str);
                    $str = preg_replace('/&nbsp;/is', '', $str);
                    preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $str, $str);
                    if (is_array($str) && ! empty($str[0])) {
                        $str = implode('', $str[0]);
                        preg_match_all("/./su", $str, $ar);
                        for ($i = 0; isset($ar[0][$i]); $i ++) {
                            $char = $ar[0][$i];
                            $chars[] = (ord($char) != 240) ? self::convertChar($char) : "?";
                        }
                    }
                    return implode('', $chars);
                    break;
            }
        } else {
            return false;
        }
    }

    /**
     * 对称加密算法：加密
     * 
     * @param string $str 密文
     * @param unknown $key 密钥
     * @return string/boolean
     */
    static public function encode($str = '', $key) {
        if (is_string($key) && ($key != '')) {
            $str = str_split(base64_encode($str));
            $count = count($str);
            foreach (str_split($key) as $k => $v) {
                $k < $count && $str[$k] .= $v;
            }
            return str_replace(array(
                '=',
                '+',
                '/'
            ), array(
                'O0O0O',
                'o000o',
                'oo00o'
            ), join('', $str));
        } else {
            return false;
        }
    }

    /**
     * 对称加密算法：解密
     * 
     * @param string $str 密文
     * @param unknown $key 密钥
     * @return string/boolean
     */
    static public function decode($str = '', $key) {
        if (is_string($key) && ($key != '')) {
            $str = str_split(str_replace(array(
                'O0O0O',
                'o000o',
                'oo00o'
            ), array(
                '=',
                '+',
                '/'
            ), $str), 2);
            $count = count($str);
            foreach (str_split($key) as $k => $v) {
                $k <= $count && $str[$k][1] === $v && $str[$k] = $str[$k][0];
            }
            $str = base64_decode(join('', $str));
            switch ($key) {
                case 'cdj_c_auth':
                case 'cdj_b_auth':
                    $str = explode('@', $str);
                    break;
                case 'cart':
                    $str = explode(',', $str);
                    break;
                default:
                    break;
            }
            return $str;
        } else {
            return false;
        }
    }

    /**
     * 检查是否为微信浏览器
     * 
     * @return number <pre>
     *         1->微信浏览器
     *         2->微信会话窗
     *         0->其他
     */
    static public function platform() {
        // 获取浏览器请求UA
        $ua = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : '';
        // 浏览器类型， 微信浏览器=>1，非微信浏览器=>0
        $res = strpos($ua, 'micromessenger') ? 1 : 0;
        // 微信会话窗口=>2，其他方式=>0
        $res = ($res == 0) && preg_match('/^mozilla\/\d+\.\d+$/i', $ua) ? 2 : $res;
        return $res;
    }

    /**
     * 随机字符串
     * 
     * @param number $length 限制长度
     * @param boolean $only_num 是否纯数字
     * @return string
     */
    static public function nonceStr($length = 16, $only_num = false) {
        $chars = $only_num ? "0123456789" : "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i ++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /**
     * 随机唯一编号生成
     * 
     * @return string
     */
    public static function sn() {
        mt_srand((double) microtime() * 1000000);
        return date('ymdHi', time()) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
    }

    /**
     * 获取加密密码
     * 
     * @param string $pswd 密码字符串
     * @return string
     */
    static public function pswd($pswd) {
        return md5($pswd . hash('sha256', md5($pswd)));
    }

    /**
     * [闲置不用]订单打印
     * 
     * @param string $deviceNo 打印机序列号
     * @param array $info 参数信息
     * @param string $type 打印机类型
     * @param string $memberCode
     * @param string $securityCode
     * @return boolean
     */
    static public function printer($deviceNo, Array $info, $type = 'a', $memberCode = '', $securityCode = '') {
        if ($deviceNo && $info) {
            $pcost = $flag = 0;
            switch ($type) {
                case 'a':
                    $message = "^N1^F0\n";
                    $message .= "^Q" . chr(strlen($info['qrcode'])) . $info['qrcode'] . "\n";
                    $message .= "^B2{$info['sname']}\r\n";
                    $message .= "订单编号：{$info['sn']}\r\n";
                    $message .= "订购时间：{$info['time']}\r\n";
                    $message .= "配送方式：{$info['dtype']}\r\n";
                    $message .= "客户称呼：{$info['uname']}\r\n";
                    if ($info['uphone'] && $info['uaddress']) {
                        $message .= "联系电话：{$info['uphone']}\r\n";
                        $message .= "送货地址：{$info['uaddress']}\r\n";
                    }
                    $message .= "--------------------------------\r\n";
                    foreach ($info['detail'] as $k => $v) {
                        $message .= ($k + 1) . "）{$v['pname']}\r\n   单价:" . sprintf('%0.2f', $v['pprice']) . "元     数量:{$v['num']}\r\n";
                        $pcost += floatval($v['num'] * $v['pprice']);
                    }
                    $pcost = sprintf('%0.2f', $pcost);
                    if ($info['remark']) {
                        $message .= "\r\n备注：{$info['remark']}\r\n";
                    }
                    $message .= "--------------------------------\r\n";
                    $message .= "^B2合计：{$pcost}元\r\n";
                    $url = "http://printer.showutech.com/api/2/service/add_order/{$deviceNo}/{$info['oid']}/";
                    $data = array(
                        'data' => $message
                    );
                    $options = array(
                        'http' => array(
                            'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                            'method' => 'POST',
                            'content' => http_build_query($data)
                        )
                    );
                    $flag = file_get_contents($url, false, stream_context_create($options));
                    $flag = explode('&', $flag);
                    $flag = $flag[0] == 'code=1' ? true : false;
                    break;
                case 'b':
                    $detail = array();
                    foreach ($info['detail'] as $k => $v) {
                        $detail[] = "{$v['pname']}@" . sprintf('%4d', $v['pprice'] * 100) . "@{$v['num']}";
                        $pcost += floatval($v['num'] * $v['pprice']);
                    }
                    $message = array(
                        'memberCode' => $memberCode,
                        'orderNo' => $info['sn'],
                        'orderCharge' => $pcost,
                        'customerDtype' => $info['dtype'],
                        'customerName' => $info['uname'],
                        'customerPhone' => $info['uphone'],
                        'customerAddress' => $info['uaddress'],
                        'customerMemo' => $info['remark'],
                        'msgDetail' => implode('||', $detail), // '番茄炒粉@1000@1||客家咸香鸡@2000@1',
                        'deviceNo' => $deviceNo,
                        'msgNo' => time() + 1,
                        'mode' => 1,
                        'reqTime' => number_format(1000 * time(), 0, '', '')
                    );
                    $content = $message['memberCode'] . $message['customerName'] . $message['customerPhone'] . $message['customerAddress'] . $message['customerMemo'] . $message['msgDetail'] . $message['deviceNo'] . $message['msgNo'] . $message['reqTime'] . $securityCode;
                    $message['securityCode'] = md5($content);
                    $flag = Core_Plugin_Http::request('http://my.feyin.net/api/sendMsg', $message, 'POST');
                    $flag = $flag ? false : true;
                    break;
            }
            return $flag;
        } else {
            return false;
        }
    }

    /**
     * 截取中文字符串
     * 
     * @param string $string 字符串
     * @param number $length 限制长度
     * @param string $ellipsis 省略部分填充
     * @param number $start 开始位置
     * @return string
     */
    static public function truncate_cn($string, $length = 0, $ellipsis = '…', $start = 0) {
        $string = strip_tags($string);
        $string = preg_replace('/\n/is', '', $string);
        $string = preg_replace('/&nbsp;/is', '', $string);
        preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $string, $string);
        if (is_array($string) && ! empty($string[0])) {
            $string = implode('', $string[0]);
            if (strlen($string) < $start + 1) {
                return '';
            }
            preg_match_all("/./su", $string, $ar);
            $string2 = '';
            $tstr = '';
            for ($i = 0; isset($ar[0][$i]); $i ++) {
                if (strlen($tstr) < $start) {
                    $tstr .= $ar[0][$i];
                } else {
                    if (strlen($string2) < $length + strlen($ar[0][$i])) {
                        $string2 .= $ar[0][$i];
                    } else {
                        break;
                    }
                }
            }
            return $string == $string2 ? $string2 : $string2 . $ellipsis;
        } else {
            $string = '';
        }
        return $string;
    }

    /**
     * 计算两个时间差
     * 
     * @param int $begin_time 开始时间戳
     * @param int $end_time 结束时间戳
     * @return array
     */
    static public function timediff($begin_time, $end_time) {
        $starttime = intval($begin_time);
        $endtime = intval($end_time);
        $timediff = $endtime - $starttime;
        $days = intval($timediff / 86400);
        $remain = $timediff % 86400;
        $hours = intval($remain / 3600);
        $remain = $remain % 3600;
        $mins = intval($remain / 60);
        $secs = $remain % 60;
        $res = array(
            "day" => $days,
            "hour" => $hours,
            "min" => $mins,
            "sec" => $secs
        );
        return $res;
    }

    /**
     * 二维数组按某个键值排序
     * 
     * @param array $list 原始列表
     * @param string $key 要排序的键名
     * @param boolen $asc 是否正序
     * @param number $offset 起始位置
     * @param number $count 单页条目数
     * @return array|boolean
     */
    public static function sort(Array $list, $key = '', $asc = true, $offset = 0, $count = 0) {
        $list = ($list && is_array($list)) ? $list : false;
        $key = ($key && is_string($key)) ? $key : false;
        $asc = is_bool($asc) ? $asc : true;
        $offset = ($offset && (intval($offset) > 0)) ? intval($offset) : 0;
        $count = ($count && (intval($count) > 0)) ? intval($count) : false;
        if ($list) {
            $res = $tmp = array();
            if ($key) {
                foreach ($list as $k => $v) {
                    $tmp[$k] = $v[$key];
                }
                $asc ? asort($tmp) : arsort($tmp);
                reset($tmp);
                foreach ($tmp as $k => $v) {
                    $res[$k] = $list[$k];
                }
            } else {
                $res = $list;
            }
            if ($count && (count($res) > $count)) {
                $res = array_slice($res, $offset, $count);
            }
            return $res;
        } else {
            return false;
        }
    }

    /**
     * 获取二维数组某个键的所有值（字符串，逗号分隔）
     * 
     * @param array $list 原始数组
     * @param string $key 键名
     * @param boolean $toStr 是否转化为字符串
     */
    public static function keys(Array $list, $key, $toStr = true) {
        $res = array();
        if ($list && is_array($list)) {
            foreach ($list as $k => $v) {
                $res[] = $v[$key];
            }
        }
        if (count($res)) {
            return $toStr ? implode(",", $res) : $res;
        }
        return false;
    }

    /**
     * 获取二维数组 某个键符合条件的重组数组
     * 
     * @param array $list 原始数组
     * @param string $key 键名
     * @param array $filter 条件
     * @return boolean/array
     */
    public static function reset(Array $list, $key, $filter) {
        $res = array();
        if ($filter && is_string($filter)) {
            if ($list && is_array($list)) {
                foreach ($list as $k => $v) {
                    $flag = false;
                    eval('$flag' . " = $v[$key]$filter;");
                    if ($flag) {
                        $res[] = $v;
                    }
                }
            }
        }
        return $res ? $res : false;
    }
}
